/*******************************************************************************
 * Copyright (c) since 2015  @Mike Tang.
 * <p/>
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 * <p/>
 * 1. Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * <p/>
 * 2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in
 * the documentation and/or other materials provided with the
 * distribution.
 * <p/>
 * 3. Neither the name of Lloyd Hilaiel nor the names of its
 * contributors may be used to endorse or promote products derived
 * from this software without specific prior written permission.
 * <p/>
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 ******************************************************************************/

package webapp.mvc.controllers;

import com.alibaba.fastjson.JSON;
import webapp.mvc.controllers.forms.SimpleResponse;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Mike
 * @project wechatshop
 * @date 8/25/15, 2:27 PM
 * @e-mail mike@mikecoder.net
 */

@Controller
@RequestMapping("/zjg12345")
public class ZJG12345Controller {

    private static final Logger logger = LogManager.getLogger(ZJG12345Controller.class);
    private static final String NULL   = null;

    @RequestMapping(value = "/orderDinner12345", method = RequestMethod.GET)
    public void orderDinner12345(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String txtPhone = request.getParameter("txtPhone");
        String TxtName = request.getParameter("TxtName");
        String OrderDate = request.getParameter("OrderDate");
        String eatHour = request.getParameter("eatHour");
        String eatMin = request.getParameter("eatMin");
        String PersonNum = request.getParameter("PersonNum");
        String IsNeedRoom = request.getParameter("IsNeedRoom");
        String OrderContent = request.getParameter("OrderContent");
        String shopId = request.getParameter("shopId");

        if (txtPhone == NULL || TxtName == NULL || OrderDate == NULL || eatHour == NULL || eatMin == NULL || PersonNum == NULL
                || IsNeedRoom == NULL || OrderContent == NULL || shopId == NULL) {
            response.getWriter().write(SimpleResponse.error(new Exception("need content")).toJSON());
            return;
        }

        if (txtPhone.equals("") || TxtName.equals("") || OrderDate.equals("") || eatHour.equals("") || eatMin.equals("")
                || PersonNum.equals("") || IsNeedRoom.equals("") || OrderContent.equals("") || shopId.equals("")) {
            response.getWriter().write(SimpleResponse.error(new Exception("need content")).toJSON());
            return;
        }

        HttpClient httpClient = new DefaultHttpClient();
        HttpGet homePage = new HttpGet("http://12345dc.com/517f/OrderState/OrderState.aspx?StoreGuid=" + shopId);
        HttpResponse res = httpClient.execute(homePage);
        String content = EntityUtils.toString(res.getEntity());
        String regex = "id=\"__VIEWSTATE\" value=\"([\\s|\\S]+?)\"";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(content);
        if (matcher.find()) {

            HttpPost order = new HttpPost("http://12345dc.com/517f/OrderState/OrderState.aspx?StoreGuid=" + shopId);

            List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
            params.add(new BasicNameValuePair("__VIEWSTATE", matcher.group(1)));
            params.add(new BasicNameValuePair("PageHead1$StoreSearch1$drpCS", ""));
            params.add(new BasicNameValuePair("PageHead1$StoreSearch1$drpArea", ""));
            params.add(new BasicNameValuePair("PageHead1$StoreSearch1$drpXF", ""));
            params.add(new BasicNameValuePair("PageHead1$StoreSearch1$txtname", ""));
            params.add(new BasicNameValuePair("__EVENTTARGET", ""));
            params.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
            params.add(new BasicNameValuePair("txtPhone", txtPhone));
            params.add(new BasicNameValuePair("TxtName", TxtName));
            params.add(new BasicNameValuePair("OrderDate", OrderDate));
            params.add(new BasicNameValuePair("eatHour", eatHour));
            params.add(new BasicNameValuePair("eatMin", eatMin));
            params.add(new BasicNameValuePair("PersonNum", PersonNum));
            params.add(new BasicNameValuePair("IsNeedRoom", IsNeedRoom));
            params.add(new BasicNameValuePair("OrderContent", OrderContent));
            params.add(new BasicNameValuePair("SubmitOrder", "提交订单"));

            order.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
            res = httpClient.execute(order);
            content = EntityUtils.toString(res.getEntity());
            if (content.contains("提交成功")) {
                response.getWriter().write(SimpleResponse.ok("success").toJSON());
            } else {
                response.getWriter().write(SimpleResponse.error(new Exception("NO")).toJSON());
            }
        }
    }

    @RequestMapping(value = "/sync12345shops", method = RequestMethod.GET)
    public void sync12345Shops(HttpServletRequest request, HttpServletResponse res) {

        try {
            res.getWriter().write(SimpleResponse.ok("SYNC OK!").toJSON());
        } catch (IOException e) {
            logger.error(e.getMessage());
        }
    }

    @RequestMapping(value = "/sync12345infos", method = RequestMethod.GET)
    public void sync12345Infos(HttpServletRequest request, HttpServletResponse res) throws IOException {
        try {
            if (this.sync12345Infos())
                res.getWriter().write(SimpleResponse.ok("SYNC OK!").toJSON());
        } catch (IOException e) {
            logger.error(e.getMessage());
            res.getWriter().write(SimpleResponse.error(new Exception(" fuck ")).toString());
        }
    }

    class Category {
        String category;
        String url;

        public String getCategory() {
            return category;
        }

        public void setCategory(String category) {
            this.category = category;
        }

        public String getUrl() {
            return url;
        }

        public void setUrl(String url) {
            this.url = url;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            Category category1 = (Category) o;

            if (category != null ? !category.equals(category1.category) : category1.category != null) return false;
            if (url != null ? !url.equals(category1.url) : category1.url != null) return false;

            return true;
        }

        @Override
        public int hashCode() {
            int result = category != null ? category.hashCode() : 0;
            result = 31 * result + (url != null ? url.hashCode() : 0);
            return result;
        }

        @Override
        public String toString() {
            return "Category{" +
                    "category='" + category + '\'' +
                    ", url='" + url + '\'' +
                    '}';
        }
    }

    class ItemInfo {
        String name;
        String address;
        String phone;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getAddress() {
            return address;
        }

        public void setAddress(String address) {
            this.address = address;
        }

        public String getPhone() {
            return phone;
        }

        public void setPhone(String phone) {
            this.phone = phone;
        }

        @Override
        public String toString() {
            return "ItemInfo{" +
                    "name='" + name + '\'' +
                    ", address='" + address + '\'' +
                    ", phone='" + phone + '\'' +
                    '}';
        }
    }

    public static void main(String[] args) throws IOException {
        ZJG12345Controller d = new ZJG12345Controller();
        d.sync12345Infos();
    }

    private boolean sync12345Infos() throws IOException {
        String URL_INFO = "http://www.zjg12345.com/zjgbmweb/ywxxtemplate/bmfw2.aspx?select=no&name=x";
        HttpClient httpClient = new DefaultHttpClient();
        HttpGet homePage = new HttpGet(URL_INFO);
        HttpResponse response = httpClient.execute(homePage);
        String content = EntityUtils.toString(response.getEntity());

        HashMap<String, LinkedList<ItemInfo>> all_info = new HashMap<>();

        String regex = "href='(bmfw2.*?)'.*?>(.*?)</a></td>";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            String url = matcher.group(1).replaceAll("[\\n|\\r|\\r\\n|\\n\\r]", "").trim();
            String name = matcher.group(2).replaceAll("[\\n|\\r|\\r\\n|\\n\\r]", "").trim().replaceAll("[张家港|张家港市]", "");

            Category category = new Category();
            category.setCategory(name);
            category.setUrl("http://www.zjg12345.com/zjgbmweb/ywxxtemplate/" + url);

            all_info.put(category.getCategory(), new LinkedList<ItemInfo>());

            HttpGet itemsGet = new HttpGet(category.getUrl());
            String itemsStr = EntityUtils.toString(httpClient.execute(itemsGet).getEntity());
            String VISIT_STATE = getViewState(itemsStr);
            String EVENT_VALID = getEventValid(itemsStr);
            //            System.out.println(itemsStr);

            if (!VISIT_STATE.equals("") && !EVENT_VALID.equals("")) {
                System.out.println(category.toString() + " @page:" + 1);
                for (int i = 2; i < 20; i++) {
                    System.out.println(category.toString() + " @page:" + i);
                    boolean isFind = false;
                    Pattern pat = Pattern
                            .compile("<a href=\"CompanyDetail.*?\" target=\"_blank\">([\\s|\\S]+?)</a></div>[\\s|\\S]+?\">([\\s|\\S]+?)</td>[\\s|\\S]+?\">([\\s|\\S]+?)</td>");
                    Matcher mat = pat.matcher(itemsStr);
                    while (mat.find()) {
                        isFind = true;
                        String _name = mat.group(1).replaceAll("[\\n|\\r|\\r\\n|\\n\\r]", "").trim().replaceAll("[张家港|张家港市]", "");
                        String _address = mat.group(2).replaceAll("[\\n|\\r|\\r\\n|\\n\\r]", "").trim().replaceAll("[张家港|张家港市]", "");
                        String _phone = mat.group(3).replaceAll("[\\n|\\r|\\r\\n|\\n\\r]", "").trim().replaceAll("[张家港|张家港市]", "");

                        ItemInfo itemInfo = new ItemInfo();
                        itemInfo.setAddress(_address);
                        itemInfo.setName(_name);
                        itemInfo.setPhone(_phone);

                        if (!all_info.get(category.getCategory()).contains(itemInfo)) {
                            all_info.get(category.getCategory()).push(itemInfo);
                        }
                    }

                    if (!isFind) {
                        break;
                    }

                    HttpPost next = new HttpPost(category.getUrl());
                    List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
                    params.add(new BasicNameValuePair("__VIEWSTATE", VISIT_STATE));
                    params.add(new BasicNameValuePair("__EVENTVALIDATION", EVENT_VALID));
                    params.add(new BasicNameValuePair("__EVENTARGUMENT", String.valueOf(i)));
                    params.add(new BasicNameValuePair("searchtype", "title"));
                    params.add(new BasicNameValuePair("__EVENTTARGET", "Service_Field_Company1$Pager"));

                    next.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
                    HttpResponse response1 = httpClient.execute(next);
                    itemsStr = EntityUtils.toString(response1.getEntity());
                }
            }
        }
        File Data = new File("zjg12345.json");
        Data.createNewFile();
        FileWriter writer = new FileWriter(Data);
        writer.write(JSON.toJSON(all_info).toString());
        writer.flush();
        writer.close();
        //        System.out.println(JSON.toJSON(all_info));
        return false;
    }

    private String getEventValid(String content) {
        String EVENTVALIDATION = "";
        String regex = "id=\"__EVENTVALIDATION\" value=\"(.*?)\"";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(content);
        if (matcher.find()) {
            EVENTVALIDATION = matcher.group(1);
        }
        return EVENTVALIDATION;
    }

    private String getViewState(String content) {
        String VISIT_STATE = "";
        String regex = "<input type=\"hidden\" name=\"__VIEWSTATE\" id=\"__VIEWSTATE\" value=\"(.*?)\".*?\\/>";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(content);
        if (matcher.find()) {
            VISIT_STATE = matcher.group(1);
        }
        return VISIT_STATE;
    }
}
